/*
*    Qizx/open 3.0 beta
*
* This code is the open-source version of Qizx.
* Copyright (C) 2004-2009 Axyana Software -- All rights reserved.
*
* The contents of this file are subject to the Mozilla Public License 
*  Version 1.1 (the "License"); you may not use this file except in 
*  compliance with the License. You may obtain a copy of the License at
*  http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
*  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
*  for the specific language governing rights and limitations under the
*  License.
*
* The Initial Developer of the Original Code is Xavier Franc - Axyana Software.
*
*/
using System;
using System.Qizx.Api;
using DataModelException = System.Qizx.Api.DataModelException;
using Node = System.Qizx.Api.Node;
using QName = System.Qizx.Api.QName;
namespace System.Qizx.Xdm
{
	
	/// <summary> Logical OR of NodeTests.</summary>
	public class UnionNodeFilter : NodeFilter
	{
        virtual public XdmNodeType NodeKind
		{
			get
			{
                XdmNodeType k1 = filters[0].NodeKind;
				for (int i = 1; i < filters.Length; i++)
				{
					if (filters[i].NodeKind != k1)
						return XdmNodeType.Unknown;
				}
				return k1;
			}
			
		}
		public NodeFilter[] filters;
		
		public UnionNodeFilter(NodeFilter t1, NodeFilter t2)
		{
			int size1 = unionSize(t1);
			int size = size1 + unionSize(t2);
			this.filters = new NodeFilter[size];
			expandUnion(t1, 0);
			expandUnion(t2, size1);
		}
		
		private void  expandUnion(NodeFilter f, int pos)
		{
			if (f is UnionNodeFilter)
			{
				UnionNodeFilter u = (UnionNodeFilter) f;
				Array.Copy(u.filters, 0, filters, pos, u.filters.Length);
			}
			else
				filters[pos] = f;
		}
		
		private int unionSize(NodeFilter f)
		{
			if (f is UnionNodeFilter)
			{
				UnionNodeFilter u2 = (UnionNodeFilter) f;
				return u2.filters.Length;
			}
			return 1;
		}
		
		public virtual void  add(NodeFilter f)
		{
			NodeFilter[] old = filters;
			int len = old.Length;
			filters = new NodeFilter[len + 1];
			Array.Copy(old, 0, filters, 0, len);
			filters[len] = f;
		}
		
		public override string ToString()
		{
			System.Text.StringBuilder buf = new System.Text.StringBuilder("UnionTest( ");
			for (int i = 0; i < filters.Length; i++)
			{
				if (i > 0)
					buf.Append(", ");
				buf.Append(filters[i]);
			}
			buf.Append(")");
			return buf.ToString();
		}
		
		public virtual bool StaticallyCheckable()
		{
			return false;
		}

        public virtual bool Accepts(XdmNodeType nodeKind, QName nodeName)
		{
			for (int i = 0; i < filters.Length; i++)
			{
				if (filters[i].Accepts(nodeKind, nodeName))
					return true;
			}
			return false;
		}
		
		public virtual bool NeedsNode()
		{
			return false;
		}
		
		public virtual bool Accepts(Node node)
		{
			try
			{
				return Accepts(node.NodeType, node.NodeName);
			}
			catch (DataModelException e)
			{
				return false;
			}
		}
	}
}